package gxwl.user.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fhs.trans.service.impl.DictionaryTransService;
import gxwl.user.entity.MenuEntityDict;
import gxwl.user.mapper.MenuDictMapper;
import gxwl.user.service.DictService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class DictServiceImpl extends ServiceImpl<MenuDictMapper, MenuEntityDict> implements DictService, InitializingBean {
    private static final String ROOT_PARENT_ID = "0";
    private final DictionaryTransService dictionaryTransService;
    @Override
    public List<Tree<String>> treeAll() {
        List<MenuEntityDict> dictList = this.list();
        List<TreeNode<String>> treeNodeList = dictList.stream().map(dic ->
                new TreeNode<>(dic.getId(), dic.getParentId(),
                        dic.getDictLabel(), dic.getSortCode()).setExtra(JSONUtil.parseObj(dic)))
                .collect(Collectors.toList());
        return TreeUtil.build(treeNodeList, "0");
    }


    @Override
    public void afterPropertiesSet() {
        this.refreshTransCache();
    }

    private void refreshTransCache() {
        // 异步不阻塞主线程，不会 增加启动用时
        CompletableFuture.supplyAsync(() -> {
            // 使用redis能解决共享问题，但是性能没有直接取缓存的好。
            dictionaryTransService.makeUseRedis();
            List<MenuEntityDict> bizDictList = super.list(new LambdaQueryWrapper<>());
            // 非root级别的字典根据ParentId分组
            Map<String, List<MenuEntityDict>> bizDictGroupByPIDMap = bizDictList.stream().filter(dict -> !ROOT_PARENT_ID
                    .equals(dict.getParentId())).collect(Collectors.groupingBy(MenuEntityDict::getParentId));
            Map<String,String> parentDictIdValMap = bizDictList.stream().filter(dict -> ROOT_PARENT_ID
                    .equals(dict.getParentId())).collect(Collectors.toMap(MenuEntityDict::getId, MenuEntityDict::getDictValue));
            for (String parentId : parentDictIdValMap.keySet()) {
                if(bizDictGroupByPIDMap.containsKey(parentId)){
                    dictionaryTransService.refreshCache(parentDictIdValMap.get(parentId), bizDictGroupByPIDMap.get(parentId).stream()
                            .collect(Collectors.toMap(MenuEntityDict::getDictValue, MenuEntityDict::getDictLabel)));
                }
            }
            return null;
        });
    }
}
